#ifndef XMETHOD_H
#define XMETHOD_H

#include "func.h"
#include <list>
#include <math.h>
#include <vector>

using namespace std;

struct w
{
	double x, y, R;
};

struct CMyPoint
{
	CMyPoint(double _x, double _y): x(_x), y(_y){}
	double x, y;
};

struct Params
{
	int steps;
	double epsilon;
	double m;
	double r;
	bool isAdaptiveConstLip;
};

typedef vector<double> Experiment;

const Params paramDefault = {10, 0.0, 0.0, 2.0, true};

class CXMethod
{
protected:
	list<w> m_W; // испытания
	CFunc *m_f; // оптимизируемая функция
	double m_m; // константа Липшица
	double m_max_tg; //максимальная вычисленная касательная
	double m_r; //параметр надёжности для адаптивной оценки константы липшица
	virtual	double d(const list<w>::iterator & it) = 0; // новая точка
	virtual	double R(const list<w>::iterator & it) = 0; // характеристика интервала
	virtual bool MUpdate(list<w>::iterator it); // вычисление адаптивной константы Липшица
	void firstMUpdate(list<w>::iterator it); // инициализация адаптивной константы Липшица
	virtual list<w>::iterator MaxR(); // поиск интервала с максимальной характеристикой

public:
	virtual void operator ()(CFunc * f, double a, double b, double &XMin, double &YMin, Params param = paramDefault)
	{
		double realepsilon;
		int realsteps;
		list<CMyPoint> Labels;
		calculate(f, a, b, param.steps, param.epsilon, param.m, param.r, param.isAdaptiveConstLip, realepsilon, realsteps, XMin, YMin, Labels);
	}
	virtual	void calculate(CFunc * f, double a, double b,
		int steps, double epsilon,
		double m, double r, bool isAdaptiveConstLip,
		double &realepsilon, int &realsteps,
		double &XMin, double &YMin, list<CMyPoint> &Labels);
	virtual void calculate_simple(CFunc * f, double a, double b, double &XMin, double &YMin);
	CXMethod(void);
	~CXMethod(void);
};


#endif
